/*
 * OPIAM Suite
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */

package opiam.admin.faare.persistence;

import java.util.ConcurrentModificationException;

/**
  * Iterator for the LazyJBTopCollection.
  */
public final class LazyJBTopIterator extends LazyIterator
{
    /**
     * Creates an iterator.
     * @param rc enclosing LazyJBTopCollection.
     */
    protected LazyJBTopIterator(LazyJBTopCollection rc)
    {
        super(rc);
    }

    /**
     * @see java.util.Iterator#next().
     */
    @Override
	public Object next()
    {
        if (getChangestamp() != getParent().getChangecount())
        {
            throw new ConcurrentModificationException(
                "Concurrent Modification is not allowed!");
        }

        if (getCursor() >= getParent().size())
        {
            return null;
        }

        Object dn;
        Object o;

        if (getCursor() < getParent().getAdded().size())
        {
            dn = getParent().getAdded().get(getCursor());
            incCursor();
            o = ((LazyJBTopCollection) getParent()).getLoaded().get(dn);

            if (o != null)
            {
                return o;
            }

            Object obj = ((LazyJBTopCollection) getParent()).lazyLoadObj(dn,
                    getParent().getUserContext());

            if (obj == null)
            {
                remove();

                return next();
            }
            else
            {
                return obj;
            }
        }
        else
        {
            // skip to the first "not deleted" dn
            dn = getParent().getValues().get(getCursor() -
                    getParent().getAdded().size());
            incCursor();

            while (isSkipped(dn))
            {
                dn = getParent().getValues().get(getCursor() -
                        getParent().getAdded().size());
                incCursor();
            }

            o = ((LazyJBTopCollection) getParent()).getLoaded().get(dn);

            if (o != null)
            {
                return o;
            }

            Object obj = ((LazyJBTopCollection) getParent()).lazyLoadObj(dn,
                    getParent().getUserContext());

            if (obj == null)
            {
                return next();
            }
            else
            {
                return obj;
            }
        }
    }
}
